/*
 * ADXL345.c
 *
 * Author: Fenris Liang
 * Copyright (c) 2011
 * All rights reserved.
 *
 */

#include "globe_var.h"
#include "ADXL345.h"
#include "stm32f10x.h"
#include "i2c.h"
#include "tool.h"
#include <stdlib.h>
#include <stdio.h>
#include "memory.h"
#include "Console.h"
#include "string.h"
//#include "ADXL335.h"

#define ADXL345_ID		0xE5

#define ADXL345_SAD_W		0xA6
#define ADXL345_SAD_R		0xA7

#define ADXL345_SAD_W_45	0x3A
#define ADXL345_SAD_R_45	0x3B

#define MULTI_RW			0x80


#define DEVID			0x00
#define THRESH_TAP		0x1D
#define OFSX			0x1E
#define OFSY			0x1F
#define OFSZ			0x20
#define DUR				0x21
#define LATENT			0x22
#define WINDOW			0x23
#define THRESH_ACT		0x24
#define THRESH_INACT	0x25
#define TIME_INACT		0x26
#define ACT_INACT_CTL	0x27
#define THRESH_FF		0x28
#define TIME_FF			0x29
#define TAP_AXES		0x2A
#define ACT_TAP_STATUS	0x2B
#define BW_RATE			0x2C
#define POWER_CTL		0x2D
#define INT_ENABLE		0x2E
#define INT_MAP			0x2F
#define INT_SOURCE		0x30
#define DATA_FORMAT		0x31
#define DATAX0			0x32
#define DATAX1			0x33
#define DATAY0			0x34
#define DATAY1			0x35
#define DATAZ0			0x36
#define DATAZ1			0x37
#define FIFO_CTL		0x38
#define FIFO_STATUS		0x39


typedef struct _LIS_INIT_TBL{
	unsigned char reg;
	unsigned char value;
}LIS_INIT_TBL;

const LIS_INIT_TBL ADXL345_Init_Tbl[] =
{
	//A
//	{ THRESH_TAP,			0x20 },
//	{ OFSX,					0x00 },
//	{ OFSY,					0x00 },
//	{ OFSZ,					0x00 },
//	{ DUR,					0x50 },	//0x00 },
//	{ LATENT,				0x20 },	//0x00 },
//	{ WINDOW,				0xF0 },	//0x00 },
//	{ THRESH_ACT, 			0xFF },
//	{ THRESH_INACT,			0xFF },
//	{ TIME_INACT,			0xFF },
//	{ ACT_INACT_CTL,		0x80 },
//	{ THRESH_FF,			0x09 },
//	{ TIME_FF,				0x14 },	//0x46 },
//	{ TAP_AXES,				0x01 },	//0x08 },
//	{ BW_RATE,				0x0C },	//0x0A },
	{ POWER_CTL,			0x08 },
	{ INT_ENABLE,			0x08 },	//0x00 },
//	{ INT_MAP,				0x00 },
	{ DATA_FORMAT,			0x0C },	//0x08 },
//	{ FIFO_CTL,				0x00 },
};


static int ADXL345_Read(unsigned char reg, char *buf, unsigned char len)
{
	if (len > 1)
		reg |= MULTI_RW;
	
	return I2C_Read(ADXL345_SAD_R, reg, (unsigned char *)buf, len);
}

/*********
static int ADXL345_Write(unsigned char reg, char *buf, unsigned char len)
{
	if (len > 1)
		reg |= MULTI_RW;
	
	return I2C_Write(ADXL345_SAD_W, reg, (unsigned char *)buf, len);
}
***********/

static int ADXL345_45_Read(unsigned char reg, char *buf, unsigned char len)
{
	if (len > 1)
		reg |= MULTI_RW;
	
	return I2C_Read(ADXL345_SAD_R_45, reg, (unsigned char *)buf, len);
}


int ADXL345_Init(void)
{
	int i;
	
	I2C_HW_Init();
    	
	for (i = 0; i < (sizeof(ADXL345_Init_Tbl)/sizeof(LIS_INIT_TBL)); i++)
	{
		I2C_Write(ADXL345_SAD_W, ADXL345_Init_Tbl[i].reg, (unsigned char *)&ADXL345_Init_Tbl[i].value, 1);
	}

	return 0;
}

int ADXL345_45_Init(void)
{
	int i;
	
	I2C_HW_Init();
    	
	for (i = 0; i < (sizeof(ADXL345_Init_Tbl)/sizeof(LIS_INIT_TBL)); i++)
	{
		I2C_Write(ADXL345_SAD_W_45, ADXL345_Init_Tbl[i].reg, (unsigned char *)&ADXL345_Init_Tbl[i].value, 1);
	}

	return 0;
}

void ADXL345_GET_XYZ(short *arg)
{
	char buf[7];
	
	ADXL345_Read(DATA_FORMAT, buf, 7);
	
	arg[0] = (((short)buf[2]) << 8) | (buf[1] & 0x00FF);
	arg[1] = (((short)buf[4]) << 8) | (buf[3] & 0x00FF);
	arg[2] = (((short)buf[6]) << 8) | (buf[5] & 0x00FF);
	
}


void ADXL345_45_GET_XYZ(short *arg)
{
	char buf[7];
	
	ADXL345_45_Read(DATA_FORMAT, buf, 7);
	
	arg[0] = (((short)buf[2]) << 8) | (buf[1] & 0x00FF);
	arg[1] = (((short)buf[4]) << 8) | (buf[3] & 0x00FF);
	arg[2] = (((short)buf[6]) << 8) | (buf[5] & 0x00FF);
	
}


unsigned char ADXL345_GET_ID(void)
{	
	char buf[2];
	ADXL345_Read(DEVID, buf, 2);
	return (unsigned char)buf[0];
}

void ADXL345_DEBUG(void)
{	
	char buf[2];
	ADXL345_Read(POWER_CTL, buf, 2);
	ADXL345_Read(DATA_FORMAT, buf, 2);
	ADXL345_Read(THRESH_TAP, buf, 2);
}